package exebuilder.controller;

import exebuilder.core.AppBuilder;
import exebuilder.core.Controllers;
import exebuilder.core.ViewLoader;
import exebuilder.data.AppConfig;
import exebuilder.data.Description;
import exebuilder.ui.MessageBox;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.net.URL;
import java.util.ResourceBundle;
import java.util.concurrent.CompletableFuture;

public class MainController implements Initializable {
  private static final Logger logger = LogManager.getLogger();
  public Label stepTitle;
  public Label stepInfo;
  public Button nextButton, backButton;
  public static int MAX_STEP = 4;
  public HBox stepButtons;
  Integer step = 0;

  AppConfig appConfig = AppConfig.getInstance();
  FirstController firstController;
  SecondController secondController;
  ThirdController thirdController;
  EndController endController;

  Parent firstView, secondView, thirdView, endView;


  @FXML
  BorderPane rootView;

  @FXML
  private void nextView() throws Exception {
    if (step == MAX_STEP) {
      CompletableFuture.runAsync(() -> {
        AppBuilder appBuilder = new AppBuilder();
        appBuilder.build();
      });
    } else {
      try {
        saveData();
      } catch (Exception e) {
        logger.error(e);
        throw e;
      }
      step += 1;
      goView();
    }
  }

  @FXML
  private void backView() {
    if (step == 0) {
      return;
    }
    step -= 1;
    goView();
  }


  private void goView() {
    var buttons = stepButtons.getChildren();

    if (step == 0 && buttons.contains(backButton)) {
      stepButtons.getChildren().remove(backButton);
    }
    if (step > 0 && !buttons.contains(backButton)) {
      stepButtons.getChildren().add(0, backButton);
    }

    if (step == MAX_STEP && buttons.contains(nextButton)) {
      nextButton.setText("开 始");
    } else {
      if (!nextButton.getText().equals("下一步"))
        nextButton.setText("下一步");
    }

    if (step == 0) {
      stepTitle.setText(Description.STEP_0_TITLE);
      stepInfo.setText(Description.STEP_0_INFO);
      rootView.setCenter(null);
    }
    if (step == 1) {
      if (firstView == null) {
        firstView = ViewLoader.load("firstView");
      }
      stepTitle.setText(Description.STEP_1_TITLE);
      stepInfo.setText(Description.STEP_1_INFO);
      rootView.setCenter(firstView);
    }
    if (step == 2) {
      if (secondView == null) {
        secondView = ViewLoader.load("secondView");
      }
      stepTitle.setText(Description.STEP_2_TITLE);
      stepInfo.setText(Description.STEP_2_INFO);
      rootView.setCenter(secondView);
    }

    if (step == 3) {
      if (thirdView == null) {
        thirdView = ViewLoader.load("thirdView");
      }
      stepTitle.setText(Description.STEP_3_TITLE);
      stepInfo.setText(Description.STEP_3_INFO);
      rootView.setCenter(thirdView);
    }
    if (step == 4) {
      if (endView == null) {
        endView = ViewLoader.load("endView");
      }
      stepTitle.setText(Description.STEP_4_TITLE);
      stepInfo.setText(Description.STEP_4_INFO);
      rootView.setLeft(null);
      rootView.setCenter(endView);
      endController = (EndController) Controllers.get("end");
      endController.showBuildInfo();
    }
  }

  private void saveData() throws Exception {
    if (this.step == 1) {
      firstController = (FirstController) Controllers.get("first");
      var appName = firstController.appNameField.getText();
      var outputPath = firstController.outputPathField.getText();
      if (firstController.guiRadioButton.isSelected()) {
        appConfig.setAppType(0);
      } else {
        appConfig.setAppType(1);
      }
      if (!StringUtils.isBlank(appName)) {
        appConfig.setAppName(appName);
      }
      if (StringUtils.isBlank(outputPath)) {
        MessageBox.error("输出目录不能为空");
        throw new Exception("输出目录不能为空");
      } else {
        appConfig.setOutputPath(outputPath);
      }
    }

    if (this.step == 2) {
      secondController = (SecondController) Controllers.get("second");
      var jdkVersion = secondController.jdkVersionComboBox.getValue();
      var jdkPath = secondController.jdkPathField.getText();
      var sourcePath = secondController.sourcePathField.getText();
      var mainJarFile = secondController.mainJarFileField.getText();
      var libPath = secondController.libPathField.getText();

      if (StringUtils.isBlank(jdkPath)) {
        MessageBox.error("JDK目录不能为空");
        throw new Exception("JDK目录不能为空");
      }
      if (StringUtils.isBlank(sourcePath)) {
        MessageBox.error("源文件目录不能为空");
        throw new Exception("源文件目录不能为空");
      }
      if (StringUtils.isBlank(mainJarFile)) {
        MessageBox.error("mainJar文件不能为空");
        throw new Exception("mainJar文件不能为空");
      }
      appConfig.setJdkVersion(jdkVersion);
      appConfig.setJdkPath(jdkPath);
      appConfig.setSourcePath(sourcePath);
      appConfig.setMainJarFile(mainJarFile);
      if (!StringUtils.isBlank(libPath)) {
        appConfig.setLibPath(libPath);
      }
    }

    if (this.step == 3) {
      thirdController = (ThirdController) Controllers.get("third");
      var iconPath = thirdController.iconPathField.getText();
      var version = thirdController.versionField.getText();
      var copyright = thirdController.copyrightField.getText();
      if (!StringUtils.isBlank(iconPath)) {
        appConfig.setIconPath(iconPath);
      }
      if (!StringUtils.isBlank(version)) {
        appConfig.setVersion(version);
      }
      if (!StringUtils.isBlank(copyright)) {
        appConfig.setCopyright(copyright);
      }
    }

    logger.debug(appConfig);
  }


  @Override
  public void initialize(URL url, ResourceBundle resourceBundle) {
    Controllers.add("main", this);
    stepTitle.setText(Description.STEP_0_TITLE);
    stepInfo.setText(Description.STEP_0_INFO);
    stepButtons.getChildren().remove(backButton);
  }
}
